﻿using System;
using System.Collections.Generic;
using System.Linq;
using Kwd.Summary.Models;
using Orchard;
using Orchard.Logging;

namespace Kwd.Summary.Services
{
  public interface IStrategyFactory : IDependency
  {
    ISummaryStrategy Default { get; }

    ISummaryStrategy Create(string name);

    ISummaryStrategy Create(SummaryPart summaryPart);

    IEnumerable<ISummaryStrategy> List();
  }

  public class StrategyFactory : IStrategyFactory
  {
    private readonly IEnumerable<ISummaryStrategy> _strategies;
    private readonly ISummaryStrategy _default;

    public StrategyFactory(IEnumerable<ISummaryStrategy> strategies)
    {
      _strategies = strategies;
      
      Logger = NullLogger.Instance;

      _default = strategies.OfType<DefaultSummary>().SingleOrDefault();
      if (_default == null){
        throw new ApplicationException("Default summary strategy not found.");
      }
    }

    public ILogger Logger { get; set; }

    public ISummaryStrategy Default { get { return _default; } }

    public ISummaryStrategy Create(string name)
    {
      if (String.IsNullOrWhiteSpace(name)) {
        Logger.Information("request for summary strategy with no name, using default");
        return _default; 
      }

      var selected = _strategies
        .Where(s => String.Compare(s.GetType().Name, name, true) == 0)
        .FirstOrDefault();

      if (selected == null)
      {
        Logger.Warning("Summary strategy {0} not found, falling back to default", name);
        selected = _default;
      }

      return selected;
    }

    public ISummaryStrategy Create(SummaryPart part)
    {
      return Create(part == null ? "" : part.StrategyName);
    }

    public IEnumerable<ISummaryStrategy> List()
    {
      var items = _strategies.OrderBy(s => s.GetType().Name);
      
      yield return Default;
      foreach (var item in items)
      {
        if (item is DefaultSummary) { continue; }
        yield return item;
      }
    }
  }
}
